package com.aop.demo.advice;

import java.util.Arrays;
import java.util.List;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.CollectionUtils;

import com.aop.demo.annotation.PermissionAnnotation;
import com.aop.demo.enums.LogicalEnum;
import com.aop.demo.response.ResultCode;
import com.aop.demo.response.ResultObj;

/**
 * 
 * @ClassName: PermissionAop
 * @Description: 权限验证注解
 * @author ldq
 * @date 2020-03-29 18:41:37
 */
@Aspect
@Configuration
public class PermissionAop {
	
	private static final Logger log = LoggerFactory.getLogger("PermissionAop");
	
	@Around(value = "@annotation(com.aop.demo.annotation.PermissionAnnotation)")
	public Object checkPermission(ProceedingJoinPoint joinPoint) throws Throwable {
		
		//HttpSession session = ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest().getSession();
        //Admin admin =(Admin) session.getAttribute("admin");//上面两行代码可以获取到request,即可以获取session
		
		//获取参数名
		MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
		PermissionAnnotation permissionAnnotation = methodSignature.getMethod().getDeclaredAnnotation(PermissionAnnotation.class);
		String[] permissions = permissionAnnotation.value();//此处可以获取@PermissionAnnotation中的注解,字符串数组
		LogicalEnum logical = permissionAnnotation.logical();
		
		if(permissions == null || permissions.length == 0) {
			log.info("permission faild：执行类及方法={}，permissions={}，{}", 
	    			methodSignature, permissions, ResultCode.PERMISSION_NO_ACCESS.getMessage());
	    	return ResultObj.failure(ResultCode.PERMISSION_NO_ACCESS);
		}
		
		//获取系统权限配置(这里根据实际情况从session或redis缓存获取用户权限信息)
		List<String> userPermissions = Arrays.asList(new String[]{"test", "ldq"});
		
		if(CollectionUtils.isEmpty(userPermissions)) {
			log.info("permission faild：执行类及方法={}，permissions={}，{}", 
	    			methodSignature, permissions, ResultCode.PERMISSION_NO_ACCESS.getMessage());
	    	return ResultObj.failure(ResultCode.PERMISSION_NO_ACCESS);
		}
		
		boolean permissionFlag = false;
		//AND
		if(LogicalEnum.AND.equals(logical)) {
			//只要一个不满足则无权限
		    for(String permission : permissions) {
		    	if(!userPermissions.contains(permission)) {
		    		permissionFlag = false;
		    		break;
		    	}
		    	permissionFlag = true;
		    }
			
		}else if(LogicalEnum.OR.equals(logical)){
			//只要一个权限满足
			for(String permission : permissions) {
		    	if(userPermissions.contains(permission)) {
		    		permissionFlag = true;
		    		break;
		    	}
		    }
		}
	    
	    if(!permissionFlag) {
	    	log.info("permission faild：执行类及方法={}，permissions={}，{}", 
	    			methodSignature, permissions, ResultCode.PERMISSION_NO_ACCESS.getMessage());
	    	return ResultObj.failure(ResultCode.PERMISSION_NO_ACCESS);
	    }
	    // 执行原方法，并记录返回值	    
		Object object = joinPoint.proceed();
		
		return object;
		
	}
}
